<template>
	<div
		@click="toDetail ? $router.push({ name: 'artistDetail', query: { id } }) : $emit('click')"
		class="position-relative flex-shrink-0"
		:style="`padding-left: ${100 / columns - 2}%;padding-top: calc(${100 / columns - 2}% + 30px);`"
	>
		<div class="position-absolute top-0 start-0 w-100 h-100">
			<div
				:class="loaded ? 'loaded' : ''"
				class="coverImage rounded-4 cursor-pointer position-relative box-border"
				:style="`background-image: url(${loaded ? picUrl : defaultMusicCover});`"
			></div>
			<div class="infoLine d-flex justify-content-between align-items-center canSelect">
				<span class="artistName fs-6 fw-bold cursor-pointer">{{ name }}</span>
				<span class="userIcon d-inline-flex rounded-circle flex-center cursor-pointer">
					<UserIcon width="15" height="15" />
				</span>
			</div>
		</div>
	</div>
</template>

<script lang="ts">
import { defineComponent, PropType, reactive, toRefs, watch } from "vue";
import { useStore } from "vuex";
export default defineComponent({
	props: {
		columns: {
			type: [String, Number],
			default: 5,
		},
		picUrl: {
			type: String,
		},
		name: {
			type: String,
		},
		toDetail: {
			type: Boolean,
			default: false,
		},
		id: {
			type: [String, Number],
		},
	},
	setup(props) {
		const store = useStore();
		const state = reactive({
			loaded: false,
			defaultMusicCover: store.state.defaultMusicCover,
		});
		const loadImage = (url) =>
			new Promise((resolve, reject) => {
				let image = new Image();
				image.onload = () => {
					resolve(url);
					image = undefined;
				};
				image.onerror = () => reject(url);
				image.src = url;
			});
		watch(
			() => props.picUrl,
			() => {
				state.loaded = false;
				loadImage(props.picUrl).then((res) => {
					state.loaded = true;
				});
			},
			{ immediate: true }
		);
		return {
			...toRefs(state),
		};
	},
});
</script>

<style scoped lang="scss">
.coverImage {
	padding-left: 100%;
	padding-top: 100%;
	background-size: cover;
	background-position: center center;
	border: 1px solid rgb(221, 221, 221);
}
.loaded {
	animation: loaded ease-in-out 0.4s forwards;
}
@keyframes loadedAnimation {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
.infoLine {
	height: 30px;
	.artistName {
		color: #333;
		&:hover {
			color: #000;
		}
	}
	.userIcon {
		width: 20px;
		height: 20px;
	}
}
.primaryTheme {
	.userIcon {
		background-image: linear-gradient(110deg, $primary, $primary, rgba($dark, 0.7));
	}
}
.darkTheme {
	.userIcon {
		background-color: $dark;
	}
}
.freeTheme {
	.userIcon {
		background-image: linear-gradient($free, rgba($dark, 0.7));
	}
}
</style>
